package calc;

public class InputParser {
	public static String Calculate(String input) {
		while(input.indexOf('(') != -1 || input.indexOf(')') != -1){
			int posOfSubExpressionStart = input.lastIndexOf('('); //Returns positions of the LAST '(' in input, (if not found, returns -1)
			int posOfSubExpressionEnd = input.indexOf(')', posOfSubExpressionStart); //Done
			
			if(posOfSubExpressionStart == -1 || posOfSubExpressionEnd == -1) throw new AshCalcException("Bracket missmatch!");
			String subExpression = input.substring(posOfSubExpressionStart+1, posOfSubExpressionEnd); //So this subExpression should be
		
			input = input.substring(0, posOfSubExpressionStart) + ODMASParser(subExpression) + input.substring(posOfSubExpressionEnd+1);
		}
		
		return "" + ODMASParser(input); 
	}
	
	private static double ODMASParser(String subExpression){
		double answer = 0;
		String operators = "^/*+-";
		
		for(int i=0; i<operators.length(); i++){
			while(subExpression.indexOf(operators.charAt(i)) != -1) {
				int opPos = subExpression.indexOf(operators.charAt(i), 1);
				double leftNum=0.0, rightNum=0.0;
				
				if(opPos == -1){
					if(subExpression.charAt(0) == '-') return Double.parseDouble(subExpression);
					else throw new AshCalcException("Illegal operator sequence!");
				}
				
				int countDown = opPos-1, countUp = Math.min(opPos+1, subExpression.length()-1);
				if(subExpression.charAt(countUp) == '-') countUp++;
				
				while(operators.indexOf(subExpression.charAt(countDown)) == -1){
					countDown--;
					if(countDown < 0) break;
				}
				
				while(operators.indexOf(subExpression.charAt(countUp)) == -1){
					countUp++;
					if(countUp >= subExpression.length()) break;
				}
				
				if (countDown != -1 && subExpression.charAt(countDown) == '-')
					if (countDown == 0 || operators.indexOf(subExpression.charAt(countDown-1)) != -1) countDown--;
				
				if(countDown == opPos || countUp == opPos) throw new AshCalcException("Empty number!");
				
				leftNum = Double.parseDouble(subExpression.substring(countDown+1,opPos));
				rightNum = Double.parseDouble(subExpression.substring(opPos+1,countUp));
				answer = elementaryOperation(leftNum, rightNum, operators.charAt(i));
				subExpression = subExpression.substring(0, countDown+1) + answer + subExpression.substring(countUp, subExpression.length());
			}
		}
		return Double.parseDouble(subExpression);
	}

	
	public static double elementaryOperation(double leftNum, double rightNum, char Operator){
		switch (Operator) {
		case '^': return Math.pow(leftNum, rightNum);
		case '/': return leftNum / rightNum;
		case '*': return leftNum * rightNum;
		case '+': return leftNum + rightNum;
		case '-': return leftNum - rightNum;
		default: throw new AshCalcException("Illegal Operator");
		}
	}
}
